<template>
  <el-dialog :title="title" :visible="menuDialogVisible" width="30%" @close="closeDialog" @open="openDialog">
    <el-tabs v-model="activeName" @tab-click="handleClick">
      <!-- 目录 -->
      <el-tab-pane label="目录" name="first">
        <el-form ref="formFirst" :rules="rulesFirst" :model="menuForm" label-width="80px">
          <el-form-item label="上级目录" prop="parentId">
            <el-cascader
              :key="keyValue"
              v-model="menuForm.parentId"
              :options="options"
              :props="cascaderProps"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item label="目录名称" prop="menuName">
            <el-input v-model="menuForm.menuName" />
          </el-form-item>
          <el-form-item label="目录路径" prop="path">
            <el-input v-model="menuForm.path" />
          </el-form-item>
          <!-- 动态显示组件路径输入框 -->
          <el-form-item v-if="menuForm.parentId !== '0' && menuForm.parentId !== ''" label="组件路径" prop="component">
            <el-input v-model="menuForm.component" placeholder="system/company/index" />
          </el-form-item>
          <el-form-item label="菜单图标" prop="icon">
            <el-select v-model="menuForm.icon" clearable placeholder="请选择图标">
              <el-option v-for="item in icons" :key="item.class" :label="item.class" :value="item.class">
                <span style="float: left">
                  <i :class="item.class" />
                </span>
                <span style="padding-left: 6px">{{ item.class }}</span>
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="显示顺序" prop="orderNum">
            <el-input-number
              v-model="menuForm.orderNum"
              controls-position="right"
              :min="1"
              :max="99"
              @change="orderNumChange"
            />
          </el-form-item>
          <el-form-item label="菜单状态" prop="status">
            <el-radio-group v-model="menuForm.status">
              <el-radio :label="false">正常</el-radio>
              <el-radio :label="true">停用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </el-tab-pane>

      <!-- 菜单 -->
      <el-tab-pane label="菜单" name="second">
        <el-form ref="formSecond" :rules="rulesSecond" :model="menuForm" label-width="80px">
          <el-form-item label="上级目录" prop="parentId">
            <el-cascader
              :key="keyValue"
              v-model="menuForm.parentId"
              :options="options"
              :props="cascaderProps"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item label="菜单名称" prop="menuName">
            <el-input v-model="menuForm.menuName" />
          </el-form-item>
          <el-form-item label="菜单路径" prop="path">
            <el-input v-model="menuForm.path" placeholder="company" />
          </el-form-item>
          <el-form-item label="组件路径" prop="component">
            <el-input v-model="menuForm.component" placeholder="system/company/index" />
          </el-form-item>
          <el-form-item label="菜单图标" prop="icon">
            <el-select v-model="menuForm.icon" clearable placeholder="请选择图标">
              <el-option v-for="item in icons" :key="item.class" :label="item.class" :value="item.class">
                <span style="float: left">
                  <i :class="item.class" />
                </span>
                <span style="padding-left: 6px">{{ item.class }}</span>
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="菜单权限" prop="perms">
            <el-input v-model="menuForm.perms" />
          </el-form-item>
          <el-form-item label="显示顺序" prop="orderNum">
            <el-input-number
              v-model="menuForm.orderNum"
              controls-position="right"
              :min="1"
              :max="99"
              @change="orderNumChange"
            />
          </el-form-item>
          <el-form-item label="菜单状态" prop="status">
            <el-radio-group v-model="menuForm.status">
              <el-radio :label="false">正常</el-radio>
              <el-radio :label="true">停用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </el-tab-pane>

      <!-- 按钮 -->
      <el-tab-pane label="按钮" name="third">
        <el-form ref="formThird" :rules="rulesThird" :model="menuForm" label-width="80px">
          <el-form-item label="选择菜单" prop="parentId">
            <el-cascader
              :key="keyValue"
              v-model="menuForm.parentId"
              :options="options"
              :props="cascaderLastlevelProps"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item label="按钮名称" prop="menuName">
            <el-input v-model="menuForm.menuName" />
          </el-form-item>
          <el-form-item label="按钮权限" prop="perms">
            <el-input v-model="menuForm.perms" />
          </el-form-item>
          <el-form-item label="显示顺序" prop="orderNum">
            <el-input-number
              v-model="menuForm.orderNum"
              controls-position="right"
              :min="1"
              :max="99"
              @change="orderNumChange"
            />
          </el-form-item>
          <el-form-item label="按钮状态" prop="status">
            <el-radio-group v-model="menuForm.status">
              <el-radio :label="false">正常</el-radio>
              <el-radio :label="true">停用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
    <span slot="footer" class="dialog-footer" style="display: flex; justify-content: center">
      <el-button size="mini" @click="closeDialog">取 消</el-button>
      <el-button type="primary" size="mini" @click="submitForm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
  import { optionsTree, insertMenu } from '@/api/menu'
  export default {
    props: {
      title: {
        type: String,
        default: '新增菜单'
      },
      menuDialogVisible: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        menuType: 'M',
        keyValue: 0,
        activeName: 'first',
        options: [], // 树形结构的数据
        menuForm: {
          parentId: '',
          menuName: '',
          icon: '',
          path: '',
          orderNum: 1,
          status: false,
          component: '',
          perms: ''
        },
        cascaderProps: {
          value: 'menuId', // 绑定选中时候的字段
          label: 'menuName', // 选择框中需要显示的明文字段
          checkStrictly: true, // 允许选择任意级别
          emitPath: false // 只返回选中的值而不是路径数组
        },
        cascaderLastlevelProps: {
          value: 'menuId', // 绑定选中时候的字段
          label: 'menuName', // 选择框中需要显示的明文字段
          checkStrictly: false, // 不允许选择任意级别,只能选择最后一级
          emitPath: false // 只返回选中的值而不是路径数组
        },
        rulesFirst: {
          parentId: [{ required: true, message: '请选择上级目录', trigger: 'blur' }],
          menuName: [{ required: true, message: '请输入目录名称', trigger: 'blur' }],
          path: [
            { required: true, message: '请输入目录路径', trigger: 'blur' },
            { pattern: /^[a-z]{4,20}$/, message: '路径只能包含英文小写字母，长度在4到20个字符之间', trigger: 'blur' }
          ],
          component: [
            { required: true, message: '请输入目录组件路径', trigger: 'blur' },
            {
              pattern: /^[a-z]+(\/[a-z]+)+$/,
              message: '路径格式错误：必须至少包含两级，各级之间用/分隔，只能包含小写字母，且不能以/开头',
              trigger: 'blur'
            }
          ],
          icon: [{ required: true, message: '请选择一个图标', trigger: 'blur' }]
        },
        rulesSecond: {
          parentId: [{ required: true, message: '请选择上级目录', trigger: 'blur' }],
          menuName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
          path: [
            { required: true, message: '请输入菜单路径', trigger: 'blur' },
            { pattern: /^[a-z]{4,20}$/, message: '路径只能包含英文小写字母，长度在4到20个字符之间', trigger: 'blur' }
          ],
          icon: [{ required: true, message: '请选择一个图标', trigger: 'blur' }],
          component: [
            { required: true, message: '请输入菜单组件路径', trigger: 'blur' },
            {
              pattern: /^[a-z]+(\/[a-z]+)+$/,
              message: '路径格式错误：必须至少包含两级，各级之间用/分隔，只能包含小写字母，且不能以/开头',
              trigger: 'blur'
            }
          ],
          perms: [
            { required: true, message: '请输入组件权限字符', trigger: 'blur' },
            {
              pattern: /^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+:[a-zA-Z0-9_]+$/,
              message: '权限字符格式应为 xxx:xxx:xxx',
              trigger: 'blur'
            }
          ]
        },
        rulesThird: {
          menuName: [{ required: true, message: '请输入按钮名称', trigger: 'blur' }],
          perms: [
            { required: true, message: '请输入按钮权限字符', trigger: 'blur' },
            {
              pattern: /^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+:[a-zA-Z0-9_]+$/,
              message: '权限字符格式应为 xxx:xxx:xxx',
              trigger: 'blur'
            }
          ]
        },
        icons: [
          {
            class: 'el-icon-s-tools'
          },
          {
            class: 'el-icon-s-custom'
          },
          {
            class: 'el-icon-setting'
          },
          {
            class: 'el-icon-user-solid'
          },
          {
            class: 'el-icon-s-help'
          },
          {
            class: 'el-icon-phone'
          },
          {
            class: 'el-icon-s-unfold'
          },
          {
            class: 'el-icon-s-operation'
          },
          {
            class: 'el-icon-more-outline'
          },
          {
            class: 'el-icon-s-check'
          },
          {
            class: 'el-icon-tickets'
          },
          {
            class: 'el-icon-s-goods'
          },
          {
            class: 'el-icon-document-remove'
          },
          {
            class: 'el-icon-warning'
          },
          {
            class: 'el-icon-warning-outline'
          },
          {
            class: 'el-icon-question'
          },
          {
            class: 'el-icon-info'
          }
        ]
      }
    },
    watch: {
      options(newVal) {
        this.keyValue++ // 监听到数据源发生变化 ，改变keyValue的值，达到重新渲染的效果
      }
    },
    methods: {
      // 关闭对话框
      closeDialog() {
        // 清理数据
        this.activeName = 'first'
        this.$emit('update:menuDialogVisible', false)
        // 清空表单数据
        this.$refs.formFirst.resetFields()
        this.$refs.formSecond.resetFields()
        this.$refs.formThird.resetFields()
        this.options = [] // 如果有必要，清空options以避免残留数据
      },
      // 提交表单
      submitForm() {
        // 表单验证
        switch (this.activeName) {
          case 'first':
            this.$refs.formFirst.validate(async isOk => {
              if (isOk) {
                if (this.menuForm.parentId === '0') {
                  this.menuForm.component = 'Layout'
                }
                this.menuForm.menuType = 'M'
                await insertMenu(this.menuForm)
                this.$message.success('添加成功')
                // 关闭对话框
                this.closeDialog()
                // 刷新数据
                this.$emit('refreshList')
              } else {
                return new Error('验证失败')
              }
            })
            break
          case 'second':
            this.$refs.formSecond.validate(async isOk => {
              if (isOk) {
                this.menuForm.menuType = 'C'
                await insertMenu(this.menuForm)
                this.$message.success('添加成功')
                // 关闭对话框
                this.closeDialog()
                // 刷新数据
                this.$emit('refreshList')
              } else {
                return new Error('验证失败')
              }
            })
            break
          case 'third':
            this.$refs.formThird.validate(async isOk => {
              if (isOk) {
                this.menuForm.menuType = 'F'
                await insertMenu(this.menuForm)
                this.$message.success('添加成功')
                // 关闭对话框
                this.closeDialog()
                // 刷新数据
                this.$emit('refreshList')
              } else {
                return new Error('验证失败')
              }
            })
            break
          default:
            break
        }
      },
      // 切换tab点击事件
      handleClick(tab, event) {
        // 清空 options 数据
        this.options = []
        switch (this.activeName) {
          case 'first':
            this.menuType = 'M'
            this.openDialog(this.menuType)
            if (this.$refs.formFirst) this.$refs.formFirst.resetFields()
            break
          case 'second':
            this.menuType = 'M'
            this.openDialog(this.menuType)
            if (this.$refs.formSecond) this.$refs.formSecond.resetFields()
            break
          case 'third':
            this.menuType = 'C'
            this.openDialog(this.menuType)
            if (this.$refs.formThird) this.$refs.formThird.resetFields()
            break
          default:
            break
        }
      },
      // 获取后端的菜单树形数据
      async openDialog() {
        const result = await optionsTree(this.menuType)
        this.options.push(result)
      },
      orderNumChange(value) {
        this.menuForm.orderNum = value
      }
    }
  }
</script>

<style>
  /* 解决控制台报错问题 */
  .el-radio input[aria-hidden='true'] {
    display: none !important;
  }

  .el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner {
    box-shadow: none !important;
  }
</style>
